using System;
using System.IO;
using Core;
using UnityEditor;
using UnityEngine;

public static class CreateProj
{
    [MenuItem("Assets/Mini Tools/Proj/Create Proj")]
    private static void Main()
    {
        var path = $"Assets/Proj/Games/s_common/Res/Conf/Table/TblGame.asset";
        var gameTbl = AssetDatabase.LoadAssetAtPath<TblGame>(path);

        foreach (var item in gameTbl.Confs)
        {
            var gameName = $"g_{item.Name}";
            CreateCode(gameName);
            CreateRes(gameName);
        }
    }

    private static void CreateCode(string gameName)
    {
        var rootProj = "Assets/Code/Game/" + gameName;
        var generalProj = "Assets/Code/Game/g_general";
        CreateDir(rootProj);
        CreateDir($"{rootProj}/Common");
        CreateDir($"{rootProj}/Common/Gene", true);
        CreateDir($"{rootProj}/Message");
        CreateDir($"{rootProj}/Message/Game");
        CreateDir($"{rootProj}/Message/Login");
        CreateDir($"{rootProj}/Data");
        CreateDir($"{rootProj}/Data/Proto", true);
        CreateDir($"{rootProj}/Data/Table", true);
        CreateDir($"{rootProj}/Feature");
        CreateDir($"{rootProj}/UI");
        CreateDir($"{rootProj}/UI/Widget");
        CreateDir($"{rootProj}/UI/Wnd");

        CopyCodeFromGeneral(rootProj, generalProj, gameName, $"Message/Game/GameEnterHandler");
        CopyCodeFromGeneral(rootProj, generalProj, gameName, $"Message/Login/LoadDataHandler");
        CopyCodeFromGeneral(rootProj, generalProj, gameName, $"Message/Login/LoginEvent");
        CopyCodeFromGeneral(rootProj, generalProj, gameName, $"Message/Login/LoginHandler");
        CopyCodeFromGeneral(rootProj, generalProj, gameName, $"UI/Wnd/Login/LoginWnd");
        CopyCodeFromGeneral(rootProj, generalProj, gameName, $"UI/Wnd/Main/MainWnd");
        CopyCodeFromGeneral(rootProj, generalProj, gameName, $"GameContext");
        
        CopyCodeFromGeneral(rootProj, generalProj, gameName, $"Feature/Scene/SceneSystem");
        CopyCodeFromGeneral(rootProj, generalProj, gameName, $"Feature/Scene/Member/LoginScene");
        CopyCodeFromGeneral(rootProj, generalProj, gameName, $"Feature/Scene/Member/MainScene");
        CopyCodeFromGeneral(rootProj, generalProj, gameName, $"Feature/Scene/Node/GeneUnitNode");
        CopyCodeFromGeneral(rootProj, generalProj, gameName, $"Feature/Scene/Node/PreloadResNode");
           
        CopyCodeFromGeneral(rootProj, generalProj, gameName, $"Feature/Unit/Unit");
        CopyCodeFromGeneral(rootProj, generalProj, gameName, $"Feature/Unit/UnitComponent");
        CopyCodeFromGeneral(rootProj, generalProj, gameName, $"Feature/Unit/UnitSystem");

    }

    private static void CreateRes(string gameName)
    {
        var rootProj = "Assets/Proj/Games/" + gameName;
        var generalProj = "Assets/Proj/Games/g_general";
        CreateDir(rootProj);
        CreateDir($"{rootProj}/Art");
        CreateDir($"{rootProj}/Art/Sprites", true);
        CreateDir($"{rootProj}/Art/Textures", true);
        CreateDir($"{rootProj}/Res");
        CreateDir($"{rootProj}/Res/Audio", true);
        CreateDir($"{rootProj}/Res/Conf");
        CreateDir($"{rootProj}/Res/Conf/Table");
        CreateDir($"{rootProj}/Res/Prefabs");
        CreateDir($"{rootProj}/Res/Prefabs/Scene");
        CreateDir($"{rootProj}/Res/Prefabs/UI");
        CreateDir($"{rootProj}/Res/Scenes");
        CreateDir($"{rootProj}/Scenes", true);
        CreateDir($"{rootProj}/Scripts", true);

        CreateTblWnd<TblWnd>($"{rootProj}/Res/Conf/Table/TblWnd.asset");
        CreateTblWnd<TblAudio>($"{rootProj}/Res/Conf/Table/TblAudio.asset");
        CreateTblWnd<TblScene>($"{rootProj}/Res/Conf/Table/TblScene.asset");

        CopyResFromGeneral(rootProj, generalProj, "Res/Scenes/Login.unity");
        CopyResFromGeneral(rootProj, generalProj, "Res/Scenes/Main.unity");
        CopyResFromGeneral(rootProj, generalProj, "Res/Prefabs/Scene/CameraDriver.prefab");
        CopyResFromGeneral(rootProj, generalProj, "Res/Prefabs/Scene/Unit.prefab");
        CopyResFromGeneral(rootProj, generalProj, "Res/Prefabs/UI/Login/LoginWnd.prefab");
        CopyResFromGeneral(rootProj, generalProj, "Res/Prefabs/UI/Main/MainWnd.prefab");
    }

    private static void CreateDir(string path, bool createEmptyFile = false)
    {
        if (Directory.Exists(path))
        {
            if (createEmptyFile)
            {
                CreateEmptyFile(path);
            }

            return;
        }

        Directory.CreateDirectory(path);
        Debug.Log($"{path} 创建成功");
        if (createEmptyFile)
        {
            CreateEmptyFile(path);
        }
    }

    private static void CreateEmptyFile(string path)
    {
        if (Utils.File.CheckFolderIsEmpty(path))
        {
            File.WriteAllText($"{path}/empty.txt", "");
        }
    }

    private static void CreateTblWnd<T>(string fullName)
        where T : ScriptableObject
    {
        if (File.Exists(fullName)) return;

        var t = ScriptableObject.CreateInstance<T>();
        //在传入的路径中创建资源
        AssetDatabase.CreateAsset(t, fullName);
        AssetDatabase.SaveAssets(); //存储资源
        AssetDatabase.Refresh(); //刷新

        Debug.Log($"{fullName} 创建成功");
    }

    private static void CopyResFromGeneral(string rootProj, string generalProj, string path)
    {
        var rootPath = Path.Combine(rootProj, path);
        if (File.Exists(rootPath)) return;

        var rootDir = Path.GetDirectoryName(rootPath);
        if (rootDir == null) return;

        if (!Directory.Exists(rootDir))
        {
            Directory.CreateDirectory(rootDir);
        }

        var generalPath = Path.Combine(generalProj, path);
        File.Copy(generalPath, rootPath);
        Debug.Log($"{rootPath} Copy 成功");
    }

    private static void CopyCodeFromGeneral(string rootProj, string generalProj, string gameName, string path)
    {
        var rootPath = Path.Combine(rootProj, $"{path}.cs");
        if (File.Exists(rootPath)) return;

        var rootDir = Path.GetDirectoryName(rootPath);
        if (rootDir == null) return;

        if (!Directory.Exists(rootDir))
        {
            Directory.CreateDirectory(rootDir);
        }

        try
        {
            var generalPath = Path.Combine(generalProj, $"{path}.txt");
            var fileContent = File.ReadAllText(generalPath);
            var modifiedContent = fileContent.Replace("__NAMESPACE__", gameName);

            File.WriteAllText(rootPath, modifiedContent);
            Debug.Log($"{rootPath} Copy 成功");
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
            throw;
        }
    }
}